package com.tiger.log.core.processing.business;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.tiger.log.common.annotation.business.json.TargetJson;
import com.tiger.log.common.entity.SysRecordLog;
import com.tiger.log.common.enums.ProcessType;
import com.tiger.log.common.exception.member.InvalidPrimaryKeyException;
import com.tiger.log.common.exception.member.NotFoundTargetJsonException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;

import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName JsonProcessing
 * @Description TODO
 * @Author huxuehao
 **/
@Component
public class JsonProcessing {

    private final CommonProcessing commonProcessing;

    public JsonProcessing(CommonProcessing commonProcessing) {
        this.commonProcessing = commonProcessing;
    }

    /**
     * 验证是否非法
     */
    public boolean isIllegal(ProceedingJoinPoint joinPoint) {
        return commonProcessing.isIllegal(joinPoint, ProcessType.JSON);
    }

    /**
     * 切入对象执行后的前置处理
     */
    public void proceedPreProcessing(@NotNull SysRecordLog recordLog, @NotNull ProceedingJoinPoint joinPoint) {
        fillRecordContent(recordLog, joinPoint);
        commonProcessing.fillRecordCollect(recordLog,joinPoint, ProcessType.JSON);
        commonProcessing.fillRecordRequest(recordLog);
    }

    /**
     * 切入对象执行后的后置处理
     */
    public void proceedPostProcessing(@NotNull SysRecordLog recordLog,Object res, boolean isCatch) {
        commonProcessing.fillRecordResult(recordLog, res, isCatch);
    }

    /**
     * 根据Content注解，从方法的参数中获取必要的内容填充SysRecordLog
     */
    public void fillRecordContent(@NotNull SysRecordLog recordLog, @NotNull ProceedingJoinPoint joinPoint) {
        Map<String, Integer> primaryKey = getPrimaryKey(joinPoint);
        for (Map.Entry<String, Integer> entry : primaryKey.entrySet()) {
            String businessData = JSON.toJSONString(joinPoint.getArgs()[entry.getValue()], JSONWriter.Feature.WriteMapNullValue);
            recordLog.setBusinessData(businessData);
            recordLog.setBusinessId(JSON.parseObject(businessData).get(entry.getKey()).toString());
        }
    }

    /**
     * 验证参数中是否存在@PrimaryKey
     */
    private Map<String, Integer> getPrimaryKey(ProceedingJoinPoint joinPoint) {
        HashMap<String, Integer> map = new HashMap<>();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        /* 获取参数 */
        Parameter[] parameters = signature.getMethod().getParameters();
        for (int index = 0; index <parameters.length; index++) {
            if ( parameters[index].isAnnotationPresent(TargetJson.class)) {
                String primaryKey = parameters[index].getAnnotation(TargetJson.class).primaryKey();
                if (primaryKey == null) {
                    throw new InvalidPrimaryKeyException();
                }
                /* primaryKey: 为主键名称; index: 为 @TargetJson 所在参数的索引 */
                map.put(primaryKey, index);
                return map;
            }
        }
        throw new NotFoundTargetJsonException();
    }
}
